/**
 * \file
 * \date 18.09.2013
 * \author alex
 */
#ifndef bullet_rviz_test_PHYSICAL_OBJECT_H_
#define bullet_rviz_test_PHYSICAL_OBJECT_H_

#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <bullet/LinearMath/btTransform.h>
#include <bullet/LinearMath/btMotionState.h>

// Bullet type forward declarations:
class btRigidBody;

namespace bullet_rviz_test
{

class PhysicalObject
{
public:
  typedef boost::function<void (PhysicalObject &)> MotionCallback;

  class MotionState : public btMotionState {
  public:
    MotionState(PhysicalObject * physical_object, const btTransform & world_transform);
    virtual ~MotionState();

    virtual void getWorldTransform(btTransform & world_transform) const;
    virtual void setWorldTransform(const btTransform & world_transform);

  private:
    PhysicalObject * physical_object_;
    btTransform world_transform_;
  };

  PhysicalObject();
  virtual ~PhysicalObject();

  virtual btRigidBody * getRigidBody() = 0;

  void registerMotionCallback(MotionCallback motion_callback);

protected:
  void notifyChangeCallbacks();

private:
  typedef std::vector<MotionCallback> MotionCallbackVector;

  MotionCallbackVector motion_callbacks_;
};

typedef boost::shared_ptr<PhysicalObject> PhysicalObjectPtr;

}

#endif /* bullet_rviz_test_PHYSICAL_OBJECT_H_ */
